package com.wuzheng.wisgo.sanitation.cloud.paraandgetutil;

/**
 * @Description: TODO
 * @Author sunpeng
 * @Date 2019/12/17 11:19
 **/

public class PointInMapArithmeticUtils {
    private double cx = 0.0D;
    private double cy = 0.0D;
    private static double r = 0.0D;

    //我国常用三个坐标系，WGS84,、北京54及西安80，而WGS84椭球的长半轴就为6378137.0
    private static final double EARTH_RADIUS = 6378137.0d;

    public PointInMapArithmeticUtils(double x, double y, double r) throws VehicleException {
        try {
            this.cx = x;
            this.cy = y;
            this.r = r;
        } catch (NumberFormatException e) {
            throw Exceptions.VehicleException(e.getMessage());
        }
    }
//    public boolean isInArea(double x, double y) {
//        return isInArea(x, y);
//    }
    public boolean isInArea(double x, double y) {
        double dis = computeLength(x, y, this.cx, this.cy);
        if (dis < this.r) {
            return true;
        }
        return false;
    }
    /*
     * @Description: 计算两点之间的距离
     * @Param: [dwStartX, dwStartY, dwEndX, dwEndY]
     * @Author: sunpeng
     * @Date: 2019/12/17
    **/
    public  double computeLength(double dwStartX, double dwStartY, double dwEndX, double dwEndY) {
        double PI = 3.1415926535898D;
        double latRadians1 = dwStartY * (PI / 180.0D);
        double latRadians2 = dwEndY * (PI / 180.0D);
        double latRadians = latRadians1 - latRadians2;
        double lngRadians = dwStartX * (PI / 180.0D) - dwEndX * (PI / 180.0D);
        //hav(A) = (1-cos(A))/2 = sin(A/2)* sin(A/2)
        double f = 2.0D * Math.asin(Math.sqrt(Math.pow(Math.sin(latRadians / 2.0D), 2.0D)
                + Math.cos(latRadians1) * Math.cos(latRadians2) * Math.pow(Math.sin(lngRadians / 2.0D), 2.0D)));
        return f * EARTH_RADIUS;
    }
    /**
     * <p>Description: 计算两点之间距离，获取一个圆半径为边长*2的正方形面积，一般用于减少大量不在圆内范围的数据</p>
     * @param dis 距离
     * @param lng 起始经度
     * @param lat 起始纬度
     * @return p[yMin][yMax][xMin][xMax]正方形范围
     */
    public  double[] getPoiRange(double dis, double lng, double lat) {
        double[] poi = new double[4];

        double lng1 = (Math.PI / 180) * lng;
        double lng2 = (Math.PI / 180) * lng;
        double lat1 = (Math.PI / 180) * lat;
        double lat2 = (Math.PI / 180) * lat;

        // 角度

        double theta = dis / EARTH_RADIUS;

        // 维度相同，反算经度
        double lngVal = Math.cos(theta) - Math.sin(lat1) * Math.sin(lat2);
        double lngThetaVal = lngVal / (Math.cos(lat1) * Math.cos(lat2));
        double elng1 = (-Math.acos(lngThetaVal) + lng1) / (Math.PI / 180);
        double elng2 = (Math.acos(lngThetaVal) + lng1) / (Math.PI / 180);

        //LogLIB.LogRun.info("elng1=" + UtilTools.format(elng1) + " elng2=" + UtilTools.format(elng2));

        // 经度相同，反算维度（根据辅助角公式计算 asinx + bcosx）
        // theta = a * Math.sin(lat2) + b * Math.cos(lat2) = Math.sqrt(a平方 + b平方)sin(x + arctan(b/a))
        double a = Math.sin(lat1);
        double b = Math.cos(lat1) * Math.cos(lng2 - lng1);
        double sqrt = Math.sqrt(Math.pow(a, 2) + Math.pow(b, 2));
        double latTheteVal = Math.cos(theta) / sqrt;
        double elat1 = (Math.asin(latTheteVal) - Math.atan(b/a)) / (Math.PI / 180);
        double elat2 = (Math.asin(-latTheteVal) - Math.atan(b/a)) / (Math.PI / 180) + 180;

        //LogLIB.LogRun.info("elat1=" + UtilTools.format(elat1) + " elat2=" + UtilTools.format(elat2));

        poi[0] = elng1;
        poi[1] = elng2;
        poi[2] = elat1;
        poi[3] = elat2;

        return poi;
    }
//    public static void main(String[] args) {
//        PointInMapArithmeticUtils mapArithmetic = null;
//        try {
//            mapArithmetic = new PointInMapArithmeticUtils(116.334616, 39.984912, 1000);
//        } catch (VehicleException e) {
//            e.printStackTrace();
//        }
//        System.out.println(mapArithmetic.isInArea("116.334606", "39.984912"));
//        double[] poiRange = getPoiRange(1000.0, 39.984912, 116.334616);
//        for (double p :poiRange) {
//            System.out.println(p);
//        }
//    }

}
